package sf_errors

import (
	"embed"
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	"golang.org/x/exp/maps"
	"strings"
)

// Error Code X XX XXX
// 第一位 1 代表系统错误，系统错误一般是系统的bug或者程序问题引起； 2 代表普通错误，普通错误一般由用户的错误操作引起
// 第二三位代表模块
//
// 01 代表用户模块
// 02 基础数据
// 03 代表权限
// 04 代表代理商模块
// 05 代表供应商模块
// 06 系统基础配置
// 07 机票模块
// 08 运价模块
// 09 财务模块
// 后三位代表具体错误编码

// 使用//go:embed指令来打包config.json文件
//
//go:embed errors.xlsx
var f embed.FS

type LangType string

const (
	CN LangType = "zh-cn" // 中文简体
	TW LangType = "zh-tw" // 中文繁体
	EN LangType = "en"    // 英文
)

type messageInfo struct {
	cn string
	tw string
	en string
}

var errorMessageMap map[int]string
var messageMap map[string]*messageInfo

func init() {
	messageMap = make(map[string]*messageInfo)
	readErrorMessage()
	errorMessageMap = make(map[int]string)
	registerSysError()
	registerUserErrors()
	registerCoreDataErrors()
	registerAgencyErrors()
	registerOrderError()
	registerFinanceErrors()
	registerSupplierError()
	registerPricingError()
	registerSysConfigErrors()
}

func readErrorMessage() {
	file, err := f.Open("errors.xlsx")
	if err != nil {
		panic(err)
	}

	// 打开文件
	excelFile, err := excelize.OpenReader(file)
	if err != nil {
		panic(err)
	}

	// 读取第一个工作表
	sheetName := excelFile.GetSheetName(0)
	if strings.EqualFold(sheetName, "") {
		sheetName = "Sheet1"
	}
	for index, row := range excelFile.GetRows(sheetName) {
		if index == 0 {
			continue
		}

		//fmt.Printf("codestr:[%s], cn:[%s], tw:[%s], en:[%s]\n", row[1], row[2], row[3], row[4])

		messageMap[strings.TrimSpace(row[1])] = &messageInfo{
			cn: strings.TrimSpace(row[2]),
			tw: strings.TrimSpace(row[3]),
			en: strings.TrimSpace(row[4]),
		}
	}
}

func GetErrorResp(locale string, code int) string {
	message := getErrorMessage(locale, code)
	if strings.EqualFold(message, "") {
		switch LangType(locale) {
		case TW:
			return fmt.Sprintf("錯誤編碼[%d]未設置錯誤消息", code)
		case EN:
			return fmt.Sprintf("Error Code [%d] No error message is set", code)
		default:
			return fmt.Sprintf("错误编码[%d]未设置错误消息", code)
		}
	}
	return message
}

func getErrorMessage(locale string, code int) string {
	if codeStr, ok := errorMessageMap[code]; ok {
		if m, ok2 := messageMap[codeStr]; ok2 {
			switch LangType(locale) {
			case CN:
				return m.cn
			case TW:
				return m.tw
			case EN:
				return m.en
			default:
				return m.cn
			}
		} else {
			return ""
		}
	} else {
		switch LangType(locale) {
		case TW:
			return fmt.Sprintf("未知編碼：【%d】", code)
		case EN:
			return fmt.Sprintf("Unknown coding: [%d]", code)
		default:
			return fmt.Sprintf("未知编码：【%d】", code)
		}
	}
}

func GetErrorMessageAll() map[int]map[string]string {
	errorArr := map[int]map[string]string{}
	codes := maps.Keys(errorMessageMap)
	for _, code := range codes {
		codeString, ok := errorMessageMap[code]
		if !ok {
			continue
		}
		message, ok := messageMap[codeString]
		if !ok {
			continue
		}
		errorArr[code] = map[string]string{
			"codeString": codeString,
			"messageCn":  message.cn,
			"messageTw":  message.tw,
			"messageEn":  message.en,
		}
	}
	return errorArr
}
